/**
 * 角色管理页面
 * 支持角色新增/编辑、权限配置、批量操作
 */

import React from 'react';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { toast } from 'sonner';
import { Container } from '@/components/ui/container';
import {
  Card,
  CardContent,
  CardHeader,
  CardTitle,
} from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Badge } from '@/components/ui/badge';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import {
  ResponsiveTable,
  ResponsiveTableHeader,
  ResponsiveTableRow,
  ResponsiveTableHead,
  ResponsiveTableCell,
  TableLoading,
  TableEmpty,
} from '@/components/ui/responsive-table';
import { TableBody } from '@/components/ui/table';
import { Checkbox } from '@/components/ui/checkbox';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import {
  FormDialog,
  BatchActionBar,
} from '@/components/system';
import { RoleForm } from './components/role-form.jsx';
import {
  adminRoleService,
  adminPermissionService,
} from '@/lib/api/services/admin-management-service.js';
import { useAdminMutation } from '@/hooks/use-admin-mutation.js';
import {
  Shield,
  Plus,
  Search,
  RefreshCw,
  Trash2,
  EllipsisVertical,
  Edit,
} from 'lucide-react';

const SYS_ROLE_FILTER_OPTIONS = [
  { label: '全部角色类型', value: 'all' },
  { label: '系统内置', value: 'true' },
  { label: '自定义', value: 'false' },
];

const formatDateTime = (value) => {
  if (!value) return '-';
  try {
    return new Date(value).toLocaleString('zh-CN', {
      year: 'numeric',
      month: '2-digit',
      day: '2-digit',
      hour: '2-digit',
      minute: '2-digit',
    });
  } catch (error) {
    return value;
  }
};

const getPermissionSummary = (permissions = []) => {
  if (!permissions.length) return '暂未分配权限';
  const names = permissions
    .map((item) => item.displayName || item.name)
    .filter(Boolean);
  if (names.length <= 3) {
    return names.join('、');
  }
  return `${names.slice(0, 3).join('、')} 等 ${names.length} 项`;
};

export default function RoleManagementPage() {
  const queryClient = useQueryClient();

  const [page, setPage] = React.useState(1);
  const [pageSize] = React.useState(20);
  const [keyword, setKeyword] = React.useState('');
  const [systemRoleFilter, setSystemRoleFilter] = React.useState('all');
  const [selectedIds, setSelectedIds] = React.useState([]);

  const [isCreateDialogOpen, setIsCreateDialogOpen] = React.useState(false);
  const [isEditDialogOpen, setIsEditDialogOpen] = React.useState(false);
  const [editingRoleId, setEditingRoleId] = React.useState(null);
  const [editingRole, setEditingRole] = React.useState(null);
  const [isLoadingRoleDetail, setIsLoadingRoleDetail] = React.useState(false);

  const queryParams = React.useMemo(() => {
    const params = { page, pageSize };
    if (keyword.trim()) params.keyword = keyword.trim();
    if (systemRoleFilter !== 'all') {
      params.systemRole = systemRoleFilter === 'true';
    }
    return params;
  }, [page, pageSize, keyword, systemRoleFilter]);

  const currentQueryKey = React.useMemo(
    () => ['admin-roles', queryParams],
    [queryParams],
  );

  const {
    data: rolesData,
    isLoading,
    error,
    refetch,
  } = useQuery({
    queryKey: currentQueryKey,
    queryFn: () => adminRoleService.getList(queryParams),
    keepPreviousData: true,
  });

  const { data: permissionTreeData, isLoading: isLoadingPermissionTree } =
    useQuery({
      queryKey: ['admin-permissions', 'tree'],
      queryFn: () => adminPermissionService.getTree(),
      staleTime: 5 * 60 * 1000,
    });

  const roles = rolesData?.data ?? [];
  const meta = {
    page: rolesData?.page ?? page,
    pageSize: rolesData?.pageSize ?? pageSize,
    total: rolesData?.total ?? 0,
    totalPages: rolesData?.totalPages ?? 1,
  };

  React.useEffect(() => {
    if (page > meta.totalPages && meta.totalPages > 0) {
      setPage(meta.totalPages);
    }
  }, [meta.totalPages, page]);

  React.useEffect(() => {
    setSelectedIds((prev) => {
      // 仅在已有选中项失效时才更新，避免重复 setState 造成无限渲染
      const filtered = prev.filter((id) =>
        roles.some((role) => role.id === id),
      );
      const unchanged =
        filtered.length === prev.length &&
        filtered.every((id, index) => id === prev[index]);
      return unchanged ? prev : filtered;
    });
  }, [roles]);

  const createRoleMutation = useAdminMutation(
    (payload) => adminRoleService.create(payload),
    {
      invalidateKeys: [['admin-roles']],
      successMessage: '角色创建成功',
      onSuccess: () => {
        setIsCreateDialogOpen(false);
      },
    },
  );

  const updateRoleMutation = useAdminMutation(
    ({ id, payload }) => adminRoleService.update(id, payload),
    {
      invalidateKeys: [['admin-roles']],
      successMessage: '角色信息已更新',
      onSuccess: () => {
        setIsEditDialogOpen(false);
        setEditingRoleId(null);
        setEditingRole(null);
      },
    },
  );

  const deleteRoleMutation = useAdminMutation(
    (id) => adminRoleService.remove(id),
    {
      invalidateKeys: [['admin-roles']],
      successMessage: '角色已删除',
      onMutate: async (id) => {
        await queryClient.cancelQueries({ queryKey: currentQueryKey });
        const previousData = queryClient.getQueryData(currentQueryKey);
        queryClient.setQueryData(currentQueryKey, (old) => {
          if (!old) return old;
          return {
            ...old,
            data: old.data.filter((role) => role.id !== id),
          };
        });
        return { previousData };
      },
      onError: (_error, _id, context) => {
        if (context?.previousData) {
          queryClient.setQueryData(currentQueryKey, context.previousData);
        }
      },
      onSuccess: (_data, id) => {
        setSelectedIds((prev) => prev.filter((item) => item !== id));
      },
      onSettled: () => {
        queryClient.invalidateQueries({ queryKey: ['admin-roles'] });
      },
    },
  );

  const batchDeleteMutation = useAdminMutation(
    async ({ ids }) => {
      await Promise.all(ids.map((id) => adminRoleService.remove(id)));
      return ids;
    },
    {
      invalidateKeys: [['admin-roles']],
      successMessage: '已批量删除角色',
      onMutate: async ({ ids }) => {
        await queryClient.cancelQueries({ queryKey: currentQueryKey });
        const previousData = queryClient.getQueryData(currentQueryKey);
        queryClient.setQueryData(currentQueryKey, (old) => {
          if (!old) return old;
          return {
            ...old,
            data: old.data.filter((role) => !ids.includes(role.id)),
          };
        });
        return { previousData };
      },
      onError: (_error, _variables, context) => {
        if (context?.previousData) {
          queryClient.setQueryData(currentQueryKey, context.previousData);
        }
      },
      onSuccess: () => {
        setSelectedIds([]);
      },
      onSettled: () => {
        queryClient.invalidateQueries({ queryKey: ['admin-roles'] });
      },
    },
  );

  const handleOpenEdit = React.useCallback(async (id) => {
    setEditingRoleId(id);
    setIsEditDialogOpen(true);
    setIsLoadingRoleDetail(true);
    try {
      const detail = await adminRoleService.getDetail(id);
      setEditingRole(detail);
    } catch (err) {
      toast.error(err?.message ?? '加载角色详情失败');
      setIsEditDialogOpen(false);
      setEditingRoleId(null);
      setEditingRole(null);
    } finally {
      setIsLoadingRoleDetail(false);
    }
  }, []);

  const handleDelete = React.useCallback(
    (role) => {
      if (role.systemRole) {
        toast.warning('系统角色不可删除');
        return;
      }
      deleteRoleMutation.mutate(role.id);
    },
    [deleteRoleMutation],
  );

  const permissionTree = permissionTreeData ?? [];
  const isPermissionTreeLoading = isLoadingPermissionTree;

  const allRowIds = roles.map((role) => role.id);
  const allSelected =
    allRowIds.length > 0 &&
    allRowIds.every((id) => selectedIds.includes(id));
  const partiallySelected =
    selectedIds.length > 0 && !allSelected;

  const handleToggleAll = (checked) => {
    if (checked) {
      setSelectedIds(allRowIds);
    } else {
      setSelectedIds([]);
    }
  };

  const handleToggleOne = (id, checked) => {
    setSelectedIds((prev) => {
      if (checked) {
        return prev.includes(id) ? prev : [...prev, id];
      }
      return prev.filter((item) => item !== id);
    });
  };

  const nonSystemSelectedIds = selectedIds.filter((id) => {
    const target = roles.find((role) => role.id === id);
    return target && !target.systemRole;
  });

  const toolbarActions = [
    {
      key: 'delete',
      icon: Trash2,
      label: '批量删除',
      variant: 'destructive',
      onClick: () => {
        if (nonSystemSelectedIds.length === 0) {
          toast.warning('请选择可删除的自定义角色');
          return;
        }
        batchDeleteMutation.mutate({ ids: nonSystemSelectedIds });
      },
      disabled:
        selectedIds.length === 0 ||
        nonSystemSelectedIds.length === 0 ||
        batchDeleteMutation.isPending,
    },
  ];

  return (
    <Container>
      <div className="flex flex-wrap items-center justify-between gap-3 mb-6">
        <div>
          <h1 className="text-3xl font-bold flex items-center gap-2">
            <Shield className="size-6 text-primary" />
            角色管理
          </h1>
          <p className="text-muted-foreground mt-1">
            查看系统与自定义角色，配置权限范围
          </p>
        </div>
        <div className="flex items-center gap-2">
          <Button
            variant="outline"
            onClick={() => refetch()}
            disabled={isLoading}
          >
            <RefreshCw className="size-4 mr-2" />
            刷新
          </Button>
          <Button
            onClick={() => setIsCreateDialogOpen(true)}
            disabled={isPermissionTreeLoading}
          >
            <Plus className="size-4 mr-1.5" />
            新建角色
          </Button>
        </div>
      </div>

      <Card>
        <CardHeader>
          <CardTitle>角色列表</CardTitle>
        </CardHeader>
        <CardContent className="space-y-4">
          <div className="grid grid-cols-1 lg:grid-cols-4 gap-4">
            <div className="col-span-1 lg:col-span-2 relative">
              <Search className="absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
              <Input
                placeholder="搜索角色名称 / 标识"
                value={keyword}
                onChange={(event) => {
                  setKeyword(event.target.value);
                  setPage(1);
                }}
                className="pl-10"
              />
            </div>

            <Select
              value={systemRoleFilter}
              onValueChange={(value) => {
                setSystemRoleFilter(value);
                setPage(1);
              }}
            >
              <SelectTrigger>
                <SelectValue placeholder="角色类型" />
              </SelectTrigger>
              <SelectContent>
                {SYS_ROLE_FILTER_OPTIONS.map((option) => (
                  <SelectItem key={option.value} value={option.value}>
                    {option.label}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>

            <Button
              variant="outline"
              onClick={() => {
                setKeyword('');
                setSystemRoleFilter('all');
                setPage(1);
              }}
            >
              清除筛选
            </Button>
          </div>

          <BatchActionBar
            selectedCount={selectedIds.length}
            onClear={() => setSelectedIds([])}
            actions={toolbarActions}
          />

          <ResponsiveTable>
            <ResponsiveTableHeader>
              <ResponsiveTableRow>
                <ResponsiveTableHead className="w-[48px]">
                  <Checkbox
                    checked={
                      allSelected ? true : partiallySelected ? 'indeterminate' : false
                    }
                    onCheckedChange={handleToggleAll}
                    aria-label="选择全部"
                  />
                </ResponsiveTableHead>
                <ResponsiveTableHead>角色名称</ResponsiveTableHead>
                <ResponsiveTableHead hideOnMobile>角色标识</ResponsiveTableHead>
                <ResponsiveTableHead hideOnTablet>系统角色</ResponsiveTableHead>
                <ResponsiveTableHead hideOnTablet>排序值</ResponsiveTableHead>
                <ResponsiveTableHead hideOnMobile>权限概览</ResponsiveTableHead>
                <ResponsiveTableHead hideOnMobile>更新时间</ResponsiveTableHead>
                <ResponsiveTableHead className="w-[100px] text-right">
                  操作
                </ResponsiveTableHead>
              </ResponsiveTableRow>
            </ResponsiveTableHeader>

            <TableBody>
              {isLoading ? (
                <TableLoading rows={5} columns={8} />
              ) : error ? (
                <ResponsiveTableRow>
                  <ResponsiveTableCell colSpan={8} className="text-center py-10">
                    <p className="text-destructive mb-4">
                      加载失败：{error.message}
                    </p>
                    <Button variant="outline" onClick={() => refetch()}>
                      重试
                    </Button>
                  </ResponsiveTableCell>
                </ResponsiveTableRow>
              ) : roles.length === 0 ? (
                <TableEmpty
                  colSpan={8}
                  icon={Shield}
                  title="暂无角色数据"
                  description="尚未创建角色或筛选条件没有匹配结果。"
                />
              ) : (
                roles.map((role) => {
                  const selected = selectedIds.includes(role.id);
                  return (
                    <ResponsiveTableRow key={role.id}>
                      <ResponsiveTableCell className="w-[48px]">
                        <Checkbox
                          checked={selected}
                          onCheckedChange={(checked) =>
                            handleToggleOne(role.id, checked)
                          }
                        />
                      </ResponsiveTableCell>

                      <ResponsiveTableCell className="space-y-1">
                        <div className="font-medium">
                          {role.displayName || role.name}
                        </div>
                        {role.description ? (
                          <div className="text-xs text-muted-foreground line-clamp-2">
                            {role.description}
                          </div>
                        ) : null}
                      </ResponsiveTableCell>

                      <ResponsiveTableCell hideOnMobile>
                        <Badge variant="outline">{role.name}</Badge>
                      </ResponsiveTableCell>

                      <ResponsiveTableCell hideOnTablet>
                        {role.systemRole ? (
                          <Badge variant="secondary">系统角色</Badge>
                        ) : (
                          <Badge variant="outline">自定义</Badge>
                        )}
                      </ResponsiveTableCell>

                      <ResponsiveTableCell hideOnTablet>
                        {role.sortOrder ?? '-'}
                      </ResponsiveTableCell>

                      <ResponsiveTableCell hideOnMobile>
                        <div className="text-sm text-muted-foreground line-clamp-2">
                          {getPermissionSummary(role.permissions)}
                        </div>
                      </ResponsiveTableCell>

                      <ResponsiveTableCell hideOnMobile>
                        <div className="text-sm text-muted-foreground">
                          {formatDateTime(role.updatedAt)}
                        </div>
                        <div className="text-xs text-muted-foreground">
                          创建：{formatDateTime(role.createdAt)}
                        </div>
                      </ResponsiveTableCell>

                      <ResponsiveTableCell className="text-right">
                        <DropdownMenu>
                          <DropdownMenuTrigger asChild>
                            <Button
                              variant="ghost"
                              size="icon"
                              className="h-8 w-8"
                            >
                              <EllipsisVertical className="size-4" />
                            </Button>
                          </DropdownMenuTrigger>
                          <DropdownMenuContent align="end">
                            <DropdownMenuItem
                              onClick={() => handleOpenEdit(role.id)}
                            >
                              <Edit className="size-3.5 mr-2" />
                              编辑
                            </DropdownMenuItem>
                            <DropdownMenuItem
                              onClick={() => handleDelete(role)}
                              className="text-destructive focus:text-destructive"
                            >
                              <Trash2 className="size-3.5 mr-2" />
                              删除
                            </DropdownMenuItem>
                          </DropdownMenuContent>
                        </DropdownMenu>
                      </ResponsiveTableCell>
                    </ResponsiveTableRow>
                  );
                })
              )}
            </TableBody>
          </ResponsiveTable>

          {meta.totalPages > 1 && (
            <div className="flex flex-wrap items-center justify-between gap-3">
              <div className="text-sm text-muted-foreground">
                第 {(meta.page - 1) * meta.pageSize + 1} -
                {' '}
                {Math.min(meta.page * meta.pageSize, meta.total)} 条 / 共 {meta.total} 条
              </div>
              <div className="flex items-center gap-2">
                <Button
                  variant="outline"
                  size="sm"
                  disabled={meta.page <= 1}
                  onClick={() => setPage((prev) => Math.max(prev - 1, 1))}
                >
                  上一页
                </Button>
                <span className="text-sm text-muted-foreground">
                  {meta.page} / {meta.totalPages}
                </span>
                <Button
                  variant="outline"
                  size="sm"
                  disabled={meta.page >= meta.totalPages}
                  onClick={() => setPage((prev) => Math.min(prev + 1, meta.totalPages))}
                >
                  下一页
                </Button>
              </div>
            </div>
          )}
        </CardContent>
      </Card>

      <FormDialog
        open={isCreateDialogOpen}
        onOpenChange={(open) => setIsCreateDialogOpen(open)}
        title="新建角色"
        description="配置角色基本信息与权限范围"
        size="xl"
      >
        <RoleForm
          mode="create"
          permissionTree={permissionTree}
          onSubmit={(payload) => createRoleMutation.mutate(payload)}
          onCancel={() => setIsCreateDialogOpen(false)}
          isSubmitting={createRoleMutation.isPending || isPermissionTreeLoading}
          disableName={false}
          disableSystemRoleToggle={false}
        />
      </FormDialog>

      <FormDialog
        open={isEditDialogOpen}
        onOpenChange={(open) => {
          if (!open) {
            setIsEditDialogOpen(false);
            setEditingRoleId(null);
            setEditingRole(null);
          }
        }}
        title="编辑角色"
        description="调整角色信息与权限配置"
        size="xl"
      >
        {isLoadingRoleDetail ? (
          <div className="py-10 text-center text-sm text-muted-foreground">
            正在加载角色信息…
          </div>
        ) : editingRole ? (
          <RoleForm
            mode="edit"
            defaultValues={editingRole}
            permissionTree={permissionTree}
            onSubmit={(payload) =>
              updateRoleMutation.mutate({ id: editingRoleId, payload })
            }
            onCancel={() => {
              setIsEditDialogOpen(false);
              setEditingRoleId(null);
              setEditingRole(null);
            }}
            isSubmitting={updateRoleMutation.isPending}
            disableName={Boolean(editingRole.systemRole)}
            disableSystemRoleToggle={Boolean(editingRole.systemRole)}
          />
        ) : (
          <div className="py-10 text-center text-sm text-muted-foreground">
            未找到角色信息。
          </div>
        )}
      </FormDialog>
    </Container>
  );
}

